# -*- coding: utf-8 -*-            
import os
import json, codecs, time, requests, os, logging
from datetime import datetime
from deprecated.sphinx import deprecated

# model-flag
MODEL_FLAG = "online"
TRAIN_FLAG = False

# Qwen-locally Debug mode
Qwen_host = os.getenv('QWEN_HOST', "127.0.0.1")
Qwen_URL = "http://{host}:8000/v1/chat/completions".format(host=Qwen_host)

# Qwen-turbo Online mode
Qwen_turbo_online_base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1"
Qwen_turbo_online_api_key = 'sk-eaa552aedca248f482e3b9906ef913a5'

if MODEL_FLAG=='online':
    MODEL_NAME = "qwen-plus-commercial"
else:
    MODEL_NAME = 'qwen-7b-opensourced'

qwen_max_retries = 1
qwen_delay = 0.1
qwen_max_length = 4000

MISSING = '客户反馈不在当前标签列表范围内'


# quality labels
class LABELS:
    def __init__(self):
        HOST = os.getenv('LABEL_HOST', '127.0.0.1')
        # HOST = os.getenv('LABEL_HOST', '152.32.135.145')
        # self.quality_labels_zh_url = "http://{host}:17400/quality_labels_zh".format(host=HOST)

        self.feeling_labels_zh_url = "http://{host}:17400/feeling_labels_zh".format(host=HOST)

        # self.forum_labels_url = "http://{host}:17400/forum_labels_zh".format(host=HOST)
        # self.purchasing_labels_url = "http://{host}:17400/purchasing_labels_zh".format(host=HOST)
        # self.sentiment_labels_zh_url = "http://{host}:17400/sentiment_labels_zh".format(host=HOST)

    # @property
    # def quality_labels_zh(self):
    #     res = requests.get(self.quality_labels_zh_url)
    #     return json.loads(res.content.decode('utf-8'))

    @property
    def feeling_labels_zh(self):
        res = requests.get(self.feeling_labels_zh_url)
        return json.loads(res.content.decode('utf-8'))

    # @property
    # def clarify_vehicle_relevant_labels(self):
    #     return [
    #         '客户反馈和车辆相关',
    #         '客户反馈和车辆不相关',
    #         '客户反馈中无法判断是否和车辆相关'
    #     ]

    # @property
    # def forum_labels(self):
    #     res = requests.get(self.forum_labels_url)
    #     return json.loads(res.content.decode('utf-8'))
    #
    # @property
    # def purchase_labels(self):
    #     res = requests.get(self.purchasing_labels_url)
    #     return json.loads(res.content.decode('utf-8'))
    #
    # @property
    # def sentiment_labels(self):
    #     res = requests.get(self.sentiment_labels_zh_url)
    #     return json.loads(res.content.decode('utf-8'))


labels = LABELS()

# label_quality_labels_zh = labels.quality_labels_zh
# label_quality_labels_en = labels.quality_labels_en
# label_quality_labels_translate = labels.quality_labels_translate

label_feeling_labels_zh = labels.feeling_labels_zh
# label_feeling_labels_convert = labels.feeling_labels_convert

# label_clarify_vehicle_relevant_labels = labels.clarify_vehicle_relevant_labels
# label_forum_labels = list(labels.forum_labels.keys())
# label_purchase_labels = list(labels.purchase_labels)
# label_sentiment_labels = labels.sentiment_labels


def write2lables(data, filename):
    with codecs.open(filename='labels/{filename}.json'.format(filename=filename),
                     mode='w', encoding='utf-8') as fw:
        json.dump(obj=data, fp=fw, ensure_ascii=False, indent=4)


write2lables(data=label_feeling_labels_zh, filename='label_feeling_labels_zh')

# write2lables(data=label_clarify_vehicle_relevant_labels, filename='label_clarify_vehicle_relevant_labels')
# write2lables(data=label_forum_labels, filename='label_forum_labels')
# write2lables(data=label_purchase_labels, filename='label_purchase_labels')
# write2lables(data=label_sentiment_labels, filename='label_sentiment_labels')


class PROMPOT:
    def __init__(self):
        ...

    def clarify_vehicle_relevant_prompt(self,
                                        customer_voice):
        """
        判断语句是否和车辆相关
        """
        # if not labels:
        #     labels = label_clarify_vehicle_relevant_labels
#         old_FORMAT = """
# ## 核心任务
# 对给定文本进行严格单标签分类，按以下规则输出
# ### **给定文本**
# {customer_voice}
# ### **处理规则**
#    - **步骤 1**：判断文本是否明确与车辆内容相关
#      **条件**：
#      - 是否涉及车辆外观内饰空间舒适性（如车身侧面、舒适性、内饰材质、空间评价等）
#      - 是否涉及车辆操控动力等评价（如转向灵活、车辆动力等）
#      - 是否涉及车辆配置或部件描述（如自动驾驶、辅助驾驶、车内功能、屏幕、空调、导航、座椅等）
#      - 是否包含车辆功能评价（如车机系统、续航、充电等）
#      - 是否包含车辆购买或售后体验（如售前价格优惠补贴、售后服务维修、车辆故障等）
#      **是 → 输出['客户反馈和车辆相关']**
#      **否 → 进入步骤 2**
#
#    - **步骤 2**：判断文本是否明确与车辆无关
#      **条件**：
#      - 是否为单纯符号（如#、@、表情符号 等）
#      - 是否为车辆无关内容（如夸赞主播、天气评论、无意义语句等）
#      **是 → 输出['客户反馈和车辆不相关']**
#      **否 → 进入步骤 3**
#
#    - **步骤 3**：无法明确判断
#      **条件**：
#      - 文本含义模糊或存在歧义
#      **直接输出['客户反馈中无法判断是否和车辆相关']**
#
# ### **执行验证**
# 模型需确保：
# - 每个给定文本均经过上述流程的严格判断
# """
        FORMAT = f"""
## 核心任务
对给定文本进行严格单标签分类，按以下规则输出列表
### 给定文本
{customer_voice}
### 处理规则
   - 步骤 1：判断文本是否包含汽车评价（车辆内饰，车辆部件，车辆外观，车辆动力操控，车辆智能化，车辆功能，智驾，智驾，车辆电池续航等）；汽车售前售后（销售价格，优惠，4S店服务，质量维修）等用户体验车辆相关内容  
     是 → 输出["客户反馈和车辆相关"]  
     否 → 进入步骤 2
   - 步骤 2：判断文本是否明确与车辆无关（如单纯表情符号、无意义短句、主播评价、短视频评论等与车辆不相关短语）
     是 → 输出["客户反馈和车辆不相关"]
     否 → 进入步骤 3
   - 步骤 3：无法明确判断给定文本是否和车辆相关
     直接输出["客户反馈中无法判断是否和车辆相关"]
### 输出示例 : json["客户反馈中无法判断是否和车辆相关"]
### 执行验证 
模型需确保：
- 每个给定文本均经过上述流程的严格判断
"""
        return FORMAT.format(customer_voice=customer_voice)

    def clarify_forum_labels(self,
                             customer_voice):
        """
            "车辆质量与可靠性",
            "车辆评价体验",
            "车辆营销内容",
            "不同车型间对比",
            "车企商业信息",
            "社区与活动",
            "其他未分类信息",
        """
        # if not labels:
        #     labels = label_forum_labels
        FORMAT = f"""
## 核心任务  
对给定文本进行分类，按以下处理规则输出
### **输入内容**  
给定文本：{customer_voice}
### **处理规则**  
1. **待输出列表建立**  
   - 建立列表：[]
2. **分步判断流程**
   - 步骤 1：判断文本是否明确属于 车辆质量与可靠性  
     条件：
     - 是否涉及车辆故障、耐用性、维修、可靠性评价等
     是 → 列表中添加"车辆质量与可靠性"
     否 → 无操作
   - 步骤 2：判断文本是否明确属于 车辆评价体验 
     条件：  
     - 是否涉及车辆外观、舒适度、设计、售前售后、车辆功能等的车辆客观用户评价体验  
     是 → 列表中添加"车辆评价体验"
     否 → 无操作
   - **步骤 3**：判断文本是否明确属于 车辆营销内容
     条件：  
     - 是否包含商业化元素描述、使用夸张营销词汇、包含促销信息、包含引导购买词语、包含模板化内容
     - 是否缺乏正常用户具体购买使用体验车辆场景
     是 → 列表中添加"车辆营销内容"
     否 → 无操作
   - 步骤 4：判断文本是否明确属于 不同车型间对比
     条件：  
     - 是否包含用户购买过程中不同车型之间的价格、设计、外观、舒适度、功能之间的对比
     是 → 列表中添加"不同车型间对比"
     否 → 无操作
   - 步骤 5：判断文本是否明确属于 车企商业信息
     条件：  
     - 是否包含车企投资信息、车企历史信息、车企产品介绍、车企产品价格、车企产品功能、车企代言人发言等
     是 → 列表中添加"车企商业信息"
     否 → 无操作
   - 步骤 6：判断文本是否明确属于 社区与活动
     条件：  
     - 是否包含车用户间线下、线上活动、用户社区活动等
     是 → 列表中添加"社区与活动"
     否 → 无操作
   - 步骤 7：判断文本是否明确属于 其他未分类信息
     条件：  
     - 当给定文本均不属上述步骤分类
     是 → 列表中添加"其他未分类信息"
     否 → 无操作
2. **输出约束** 
   - **准确性**：严格按步骤顺序判断，禁止跳过步骤直接输出。  
   - **禁止解释**：仅输出标签，不添加任何说明或分析。
### **输出格式**
直接输出结果，格式如:json["车辆质量与可靠性", "车辆评价体验"]  
### **执行验证**
模型需确保:
1. 给定文本均经过步骤1→步骤7的完整流程
2. 输出标签与给定条件完全匹配，无截断或修改
"""
        return FORMAT.format(customer_voice=customer_voice,
                             labels=str(labels))


    def relevant_sentence_prompt(self,
                                 customer_voice,
                                 vehicle):
        '''
        这个方法会将原始语句打散为列表
        cuzu_analysis的时候，按照列表进行逐个分析
        purchase时候，按照全文全部加进去分析

        主要的核心任务是剔除所有不相干的车型，仅保留相关的车型信息
        '''
        FORMAT = f'''
## 核心任务
从给定文本中逐句提取与目标车型 {vehicle} 相关的片段，按以下规则构建输出列表。
### **给定文本**
{customer_voice}
### **处理规则**
1. **片段锚点建立**
- 将文本按中文标点符号（句号、感叹号、问号、#）分割为独立片段
- **示例**:
 原文：`A。B！C？#D` → 分割为 `["A", "B", "C", "D"]`
- **注意**：仅作给定文本切分，不可遗漏给定文本中的任何片段
2. **逐片段处理流程**
对每个片段执行以下步骤:
- **Step 1**：判断片段是否仅提及**其他车型**（如仅提及 *非{vehicle}* 车型名称、品牌名称等）
 - **是** → 忽略此片段
 - **否** → 进入 Step 2
- **Step 2**：→ 加入输出列表
3. **输出约束**  
- **禁止修改**：保留片段原文，包括标点、错别字或语法错误。  
- **禁止增删**：仅筛选片段，不合并、拆分或重组句子。  
### **输出要求**  
直接输出输出列表，格式如：json["片段1", "片段2"]
### **执行验证**
模型需确保:
- 每个片段均经过上述流程的严格判断。
- 输出列表中的片段与原文完全一致，无任何修改。
'''
        return FORMAT.format(customer_voice=customer_voice,
                             vehicle=vehicle)

    def purchase_prompt(self,
                        customer_voice):
        '''
        强烈购买车辆意愿
        中等购买车辆意愿
        低购买车辆意愿
        无法判别购车意愿
        '''
        FORMAT = f"""
## 核心任务
从给定文本中判断用户购车意愿，按以下处理规则逐步执行
### **给定文本**
{customer_voice}
### **处理规则**
1. **处理流程**
对给定文本逐步执行以下步骤：
   - **步骤 1**：判断文本是否明确属于 强烈购买车辆意愿
     **条件**：
     - 是否指定文本包含已经购买、购买决定、购车计划、试驾、付款定金、车辆感受好评等表达购买意愿 或者 购买后的车辆抱怨（质量抱怨，售后抱怨，价格浮动抱怨等）的内容
     是 → 直接返回["强烈购买车辆意愿或已购车"]
     否 → 进入步骤 2
   - **步骤 2**：判断文本是否明确属于 中等购买车辆意愿
     **条件**：
     - 是否指定文本包含潜在兴趣表达、车辆信息询问、车型对比、预算需求模糊等表达购买意愿犹豫的内容
     **是 → 直接返回["中等购买车辆意愿"]
     **否 → 进入步骤 3
   - **步骤 3**：判断文本是否明确属于 低购买车辆意愿
     **条件**：
     - 是否指定文本包含弱兴趣表达、预算或需求不匹配、车型外观内饰功能负面评价等
     **是 → 直接返回["低购买车辆意愿"]
     **否 → 进入步骤 4
   - **步骤 4**：无法判别
     直接返回["无法判别购车意愿"]
2. **输出约束**
   - **准确性**：严格按步骤1→4顺序判断，禁止跳过步骤
   - **单标签输出**：仅输出一个标签，禁止多标签或混合结果
   - **无解释**：仅按照规则返回，不添加任何说明
### **输出格式**
直接输出结果，格式如:json["无法判别购车意愿"]
### **执行验证**
模型需确保：
1. 给定文本均经过步骤1→步骤4的完整流程
2. 输出标签与给定条件完全匹配，无截断或修改
"""
        return FORMAT.format(
            customer_voice=customer_voice
        )


    def sm_label_1_prompt(self,
                          customer_voice):
                        # labels
                        # vehicle
        """
        这个因为本身就有复杂性，所以就不再引入vehicle，将模型变得更复杂了
        """
        FORMAT = f"""
## 核心任务
将给定文本按照如下处理规则精准分类，构建输出列表
### **给定文本**
{customer_voice}
### **处理步骤流程**
1. 给定文本是否涉及车辆外部可视部件（如车身尺寸、轮毂、刹车卡钳、前后灯组）；外观感受（如设计风格、颜色、漆面）
   - 是 → 输出列表添加"车辆外观"
2. 给定文本是否涉及车身结构部件（如车辆底盘、转向、悬架、制动传动、方向盘、车门车顶、化妆镜）；空调功能或设置；座椅相关（儿童座椅、座椅加热通风等）；车辆灯光音响（氛围灯、阅读灯、音量调节、车外声音交互）
   - 是 → 输出列表添加"车身部件或空调或座椅或底盘或灯光音响"
3. 给定文本是否涉及车内空间感受（头部腿部空间、横向空间、储物空间、收纳空间、前后备箱空间）
   - 是 → 输出列表添加"车内空间"
4. 给定文本是否涉及驾驶操控感受（转向、刹车、加速、车身稳定性抓地力、爬坡下坡感受）；动力性能（功率扭矩、百公里加速、驱动类型、动力系统）
   - 是 → 输出列表添加"车辆操控体验或动力性能"
5. 给定文本是否涉及车辆舒适性（座椅舒适性、隔音、减震、防晒、乘坐视野、地板平整度）；车内便利性（上下车便利性）
   - 是 → 输出列表添加"车辆使用舒适性或便利性"
6. 给定文本是否涉及车辆购买费用（价格、折扣促销优惠、订金、补贴、金融服务贷款等）；车辆使用成本（油费电费成本、维修保养、订阅等）
   - 是 → 输出列表添加"车辆购买价格优惠或车辆使用成本"
7. 给定文本是否涉及车辆内饰（内饰工艺、材质、颜色搭配、车辆座椅等部件材质）；车辆按键
   - 是 → 输出列表添加"车辆内饰或车内按键"
8. 给定文本是否涉及车辆屏幕（中控屏、仪表屏、后排屏）；HUD
   - 是 → 输出列表添加"车辆屏幕或HUD"
9. 给定文本是否涉及车载应用（车内视频音频、支付、信息等应用服务）；车机导航（导航地图、路径规划）
   - 是 → 输出列表添加"车载应用或车机导航"
10. 给定文本是否涉及车辆座舱内模式（露营模式、工作学习模式）；座舱AI（语音识别交互、手势识别、声源定位）；其他座舱功能（手机充电、投屏、蓝牙）
   - 是 → 输出列表添加"车辆座舱内功能"
11. 给定文本是否涉及车辆续航（续航可信度、续航表现）；电池（电池加热、热管理、衰减、电池外放电功能、能量回收）；电机电驱
   - 是 → 输出列表添加"车辆电池电机电驱续航等"
12. 给定文本是否涉及车辆充电放电（充电速度、慢充快充、充电功率）；充电桩；换电
   - 是 → 输出列表添加"车辆充电换电"
13. 给定文本是否涉及驾驶辅助（车道保持、盲区监测、拨杆变道等辅助驾驶功能）；泊车辅助（泊车功能，智能召唤，倒车辅助）；智驾（城市内自动驾驶，AI领航辅助等）
   - 是 → 输出列表添加"驾驶辅助或泊车辅助或自动驾驶"
14. 给定文本是否涉及售前用户体验（销售体验、试乘试驾、门店、交车服务）；售后体验（维修保养、客户关怀、车友社区、充电桩体验、二手车）
   - 是 → 输出列表添加"车辆售前或售后服务"
15. 给定文本是否涉及车辆安全（雷达、摄像头、行车记录仪、后视镜、哨兵模式、车身防撞材质等）；乘客安全（司机注意力监测、声纹识别、面部识别）
   - 是 → 输出列表添加"车辆安全或乘客安全保护"
16. 给定文本是否涉及车辆品牌（品牌知名度、档次、车企口碑）
   - 是 → 输出列表添加"车辆品牌形象"
17. 给定文本是否涉及车机交互（车机交互、车机UI设计、车机输入法、车机手势控制等）
   - 是 → 输出列表添加"车机图形界面交互"
18. 给定文本是否涉及车辆和其他互联（车联网、远程控制）；车辆质量耐用性；车辆云端服务（软件云端升级、紧急救援）；其他软硬件系统（车辆电子电器架构、车辆操作系统）
   - 是 → 输出列表添加"车辆其他功能"
**输出约束**
- **准确性**：严格按步骤1→18顺序判断，禁止跳过步骤
- **无解释**：仅按照规则返回，不添加任何说明
- 如果步骤1→18均无法匹配，直接输出[]
### **输出格式**
直接输出结果，格式如:json["车辆外观", "车辆操控体验或动力性能"]
### **执行验证**
1. 给定文本均经过步骤1→步骤4的完整流程
"""
        return FORMAT.format(
            customer_voice=customer_voice,
            labels=labels
        )

    def sm_label_2_prompt(self,
                          customer_voice,
                          labels):
        labels_format = ''
        for label in labels:
            labels_format += f"{label}\n"
        FORMAT = f"""
## 核心任务
将给定文本按照如下处理规则精准分类，构建输出列表
### **给定文本**
{customer_voice}

### **标签体系如下**
{labels_format}
### **标签体系如上**

### **处理规则**
1. 将给定文本与标签体系逐行匹配，判断是否和该行标签强相关（给定文本包含标签关键词；给定文本与标签强相关）
    - *是* -> 输出列表添加 该行标签
    - *否* -> 忽略该行标签
**输出约束**
- **准确性**：严格按处理规则逐行匹配标签体系
- **禁止修改新增标签**：禁止添加不在标签体系中的标签，禁止截断标签
- **无解释**：仅按照规则返回，不添加任何说明
- 如果给定文本均与标签体系中标签无关，直接输出[]
### **输出格式**
直接输出结果，格式如:json["车身线条", "座椅按摩"]
"""
        return FORMAT.format(
            customer_voice=customer_voice,
            labels_format=labels_format
        )


    def ner_prompt(self,
                   customer_voice,
                   content):
        FORMAT = f"""
## 核心任务
从给定文本中提取与目标标签 {content} 相关的片段，按以下规则构建输出列表
### **给定文本**
{customer_voice}
### **处理规则**
1. **文本片段锚点建立**
- 提取给定文本中与 {content} 强相关的片段（给定文本包含标签关键词；给定文本与标签强相关）
2. **逐个文本片段处理流程**
- 判断该片段是否与 {content} 强相关（该片段包含 {content} 关键词或意义强相关）
 - **是** → 加入输出列表
 - **否** → 忽略此片段
3. **输出约束**
- **禁止修改**：保留片段原文，包括标点、错别字或语法错误。
### **输出要求**
直接输出输出列表，格式如：json["片段1", "片段2"]
"""

        return FORMAT.format(
            customer_voice=customer_voice,
            content=content
        )

    def sentiment_prompt(self,
                         customer_voice,
                         content,
                         vehicle):
        # if not labels:
        #     labels = label_sentiment_labels
        if len(vehicle) :
            FORMAT = f"""
## 核心任务
从给定文本中 **站在{vehicle}的角度** 判断用户情感倾向，按以下处理规则逐步执行
### **给定文本**
{customer_voice}
### **处理规则**
1. **处理流程**
对给定文本逐步执行以下步骤：
   - 步骤 1：判断给定文本是否包含 {content} 强相关的片段（给定文本包含标签关键词；给定文本与标签强相关）
     是 → 进入步骤 2
     否 → 直接返回[]
   - 步骤 2：
     条件：是否给定文本 {content} 相关内容站在{vehicle}角度为基本符合用户需求、或单纯指出配置的参数、功能的名称、内饰外观等的参数等 表述没有明显情感倾向
     是 → 直接返回["中性情感-3"]
     否 → 进入步骤 3
   - 步骤 3：
     条件：是否给定文本 {content} 相关内容站在{vehicle}角度明显表达好评、赞誉等极端正向情感
     是 → 直接返回["正向情感-5"]
     否 → 进入步骤 4
   - 步骤 4：是否给定文本 {content} 相关内容站在{vehicle}角度略微表达好评、赞誉等轻微正向情感
     是 → 直接返回["正向情感-4"]
     否 → 进入步骤 5
   - 步骤 5：是否给定文本 {content} 相关内容站在{vehicle}角度略微表达不满、产品存在部分不足但能接受、用户期望改进等轻微负向情感
     是 → 直接返回["负向情感-2"]
     否 → 进入步骤 6  
   - 步骤 6：否给定文本 {content} 相关内容站在{vehicle}角度包含极端不满、产品存在严重不足、产品严重影响用户体验等极端负向情感
     是 → 直接返回["负向情感-1"]
     否 → 进入步骤 7 
   - 步骤 7：直接返回["中性情感-3"]
2. **输出约束**
   - **准确性**：严格按步骤1→7顺序判断，禁止跳过步骤
   - **单标签输出**：仅输出一个标签，禁止多标签或混合结果
   - **无解释**：仅按照规则返回，不添加任何说明
### **输出格式**
直接输出结果，格式如:json["中性情感-3"]
"""
            return FORMAT.format(
                customer_voice=customer_voice,
                content=content,
                vehicle=vehicle
            )
        else:
            FORMAT = f"""
## 核心任务
从给定文本中判断用户情感倾向，按以下处理规则逐步执行
### **给定文本**
{customer_voice}
### **处理规则**
1. **处理流程**
对给定文本逐步执行以下步骤：
   - 步骤 1：判断给定文本是否包含与 {content} 强相关的片段（给定文本包含标签关键词；给定文本与标签强相关）
     是 → 进入步骤 2
     否 → 直接返回[]
   - 步骤 2：
     条件：是否给定文本 {content} 相关内容为基本符合用户需求、或单纯指出配置的参数、功能的名称、内饰外观等的参数等 表述没有明显情感倾向
     是 → 直接返回["中性情感-3"]
     否 → 进入步骤 3
   - 步骤 3：
     条件：是否给定文本 {content} 相关内容明显表达好评、赞誉等极端正向情感
     是 → 直接返回["正向情感-5"]
     否 → 进入步骤 4
   - 步骤 4：是否给定文本 {content} 相关内容略微表达好评、赞誉等轻微正向情感
     是 → 直接返回["正向情感-4"]
     否 → 进入步骤 5
   - 步骤 5：是否给定文本 {content} 相关内容略微表达不满、产品存在部分不足但能接受、用户期望改进等轻微负向情感
     是 → 直接返回["负向情感-2"]
     否 → 进入步骤 6
   - 步骤 6：否给定文本 {content} 相关内容包含极端不满、产品存在严重不足、产品严重影响用户体验等极端负向情感
     是 → 直接返回["负向情感-1"]
     否 → 进入步骤 7
   - 步骤 7：直接返回["中性情感-3"]
2. **输出约束**
   - **准确性**：严格按步骤1→7顺序判断，禁止跳过步骤
   - **单标签输出**：仅输出一个标签，禁止多标签或混合结果
   - **无解释**：仅按照规则返回，不添加任何说明
### **输出格式**
直接输出结果，格式如:json["中性情感-3"]
"""
            return FORMAT.format(
                customer_voice=customer_voice,
                content=content
            )


prompt_toolkit = PROMPOT()


